package com.qm.finger;

import android.serialport.SerialPort;


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SerialManagerClass {
    private static final String TAG = "SerialManagerClass";
    public SerialPort mSerialPort;
    public String serialName;
    private OutputStream mOutputStream;
    private InputStream mInputStream;
    private boolean isOpen = false;
    private Lock lock = null;
    private volatile boolean recThreadRun = false;

    public InputStream openSerialPort(String serialPortPath, int baud) {
        if (serialPortPath.equals("") || serialPortPath == null) {
            return mInputStream;
        } else {
            if (!isOpen) {
                try {
                    File serialFile = new File(serialPortPath);
                    if (!serialFile.canRead() || !serialFile.canWrite()) {
                        isOpen = false;
                        return mInputStream;
                    }
                    mSerialPort = new SerialPort(serialFile, baud, 0);
                    serialName = serialPortPath;
                    mInputStream = mSerialPort.getInputStream();
                    mOutputStream = mSerialPort.getOutputStream();
                    recThreadRun = true;
                    isOpen = true;
                    if (lock == null)
                        lock = new ReentrantLock();
                } catch (IOException | SecurityException e) {
                    e.printStackTrace();
                    isOpen = false;
                }
            }
        }

        return mInputStream;
    }


    public boolean isSerialPortOpened() {
        return isOpen;
    }

    public boolean closeSerialPort() {
        recThreadRun = false;
        if (mSerialPort != null) {
            mSerialPort.close();
            isOpen = false;
        }
        return isOpen;
    }
    public InputStream getInputStream() {
        return mInputStream;
    }
    public boolean sendData(byte[] data) {
        if (!isOpen) return false;
        try {
            mOutputStream.write(data);
            mOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    //只发送指令 读取另外进行
    public int sendFingerCommand(byte[] sendBT){
        if (lock == null)
            lock = new ReentrantLock();
        lock.lock();//上锁
        int readLen = 0;
        if (!isOpen) {
            lock.unlock();
            return -1;
        }
        try {
            readLen = mInputStream.available();
            if (readLen > 0) {
                mSerialPort.tcflush();
            }
            mOutputStream.write(sendBT);
            mOutputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
            lock.unlock();
            return -1;
        }
        lock.unlock();
        return 0;
    }
    public int sendCommand(boolean isRead, byte[]... data) {
        if (lock == null)
            lock = new ReentrantLock();
        lock.lock();//上锁
        int ret = 0;
        int readLen = 0;
        if (!isOpen) {
            lock.unlock();
            return -1;
        }
        byte[] hexBytes = data[0];
        try {
            readLen = mInputStream.available();
            if (readLen > 0) {
                mSerialPort.tcflush();
            }
            mOutputStream.write(hexBytes);
            mOutputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
            lock.unlock();
            return -1;
        }
        if (!isRead) {
            lock.unlock();
            return 66;
        }
        int readTimes = 10;
        while (readTimes-- > 0) {
            try {
                readLen = mInputStream.available();
                Thread.sleep(50);
                if (readLen > 0 && readLen >= mInputStream.available()) {
                    if (readLen >= data[1].length) {
                        ret = mInputStream.read(data[1], 0, data[1].length);
                    } else {
                        ret = mInputStream.read(data[1], 0, readLen);
                    }
                    break;
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        }
        lock.unlock();
        return ret;
    }
}
